/**
 * Created by hjqi on 2016/1/20.
 */

var express = require('express');
var cheerio = require('cheerio');
var fs = require('fs');
var Promise = require('promise');
var http = require('http');
var qs = require('querystring');
var router = express.Router();
var path=require('path');
var jobBuildInfoCol = require('../lib/config/config').config.mongodb.jobBuildInfo_collection;
var JobBuildInfoDB = require('../db/jobBuildInfoDB');
var _jobBuild = new JobBuildInfoDB(jobBuildInfoCol);
var logger = require('../lib/log4js/log4js').logger('opBuildInfo');
var httpRequest = require('../lib/common/httpRequest').httpRequest;
var _rep = new httpRequest();
var config = require('../lib/config/config').config;
var _splitflag = "-";
var _getTokenAndUser = require('../lib/common/common').getTokenAndUser;
var myRet = require('../lib/common/common').myReturn;
var _exec_jenkins_shell = '#!/bin/bash\n' +
    'git config --global http.postBuffer 1024M \n'+
    'isGitDir=`git rev-parse --is-inside-work-tree 2>/dev/null`\n' +
    'if [ "$isGitDir" != "true" ];then\n' +
    '  git init \n' +
    'fi \n' +
    'git fetch --tags --progress #[git_path] +refs/heads/*:refs/remotes/origin/* \n' +
    'if [ $? -ne 0 ];then \n' +
    '   echo "failed" \n' +
    '   exit 1 \n' +
    'else \n' +
    '   echo "------------------------------------" \n' +
    'fi \n' +
    'if [ ${TAG_NAME} == "master" ];then \n ' +
    '   git checkout origin/master \n' +
    '   git reset --hard origin/master \n'+
    '       exit 0 \n'+
    'else \n' +
    '   if [ ${BRANCH_TYPE} == "branch" ];then \n' +
    '       git checkout origin/${TAG_NAME} \n'+
    '       git reset --hard origin/${TAG_NAME} \n'+
    '       exit 0 \n'+
    '   else \n' +
    '       git checkout ${TAG_NAME} \n'+
    '       git reset --hard ${TAG_NAME} \n'+
    '       exit 0 \n'+
    '   fi \n' +
    'fi \n';


var _exec_svn_jenkins_shell = '#!/bin/bash\n' +
    'if [ ${TAG_NAME} == "master" ];then\n ' +
    '   svnPath="#[svn_path] master" \n' +
    'else \n' +
    '   svnPath="#[svn_path]" \n'+
    '   svnPath=${svnPath%/*}"/${TAG_NAME}" \n'+
    'fi \n'+
    'svn co $svnPath  --username "#[username]" --password "#[password]" --non-interactive  \n';
var _autoupdate_shell ='if  [ ${status} ];then\n'+
    ' if [ ${type} ];then\n'+
    '  curl -s -d #[repoName]:${TAG_NAME} #[updateUrl]/update/Response\n'+
    ' fi\n'+
    'fi\n';
var create_tpl = cheerio.load(fs.readFileSync('./config/createJob.tpl','utf-8'),{
    ignoreWhitespace: true,
    xmlMode: true,
    lowerCaseTags: false
});

create_tpl('uri').text('unix:///var/run/docker.sock');
//registry uri
//create_tpl('builders url').text('http://'+config.register.host+":"+config.register.port);
create_tpl('builders url').text('http://'+config.register.interaddr);
function _request(url,method,data,cb,ctype){

    if(ctype === undefined)
        ctype = 'text/xml';

     var opt = {
            host:config.jenkins.host,
            port:config.jenkins.port,
            method: method,
            path: url,
            headers: {
                'Content-Type': ctype,
                'Content-Length': data.length
            }
        };


    var request =http.request(opt,function(response){
        var postData = "";
        response.addListener("data", function (postDataChunk) {
            postData += postDataChunk;
        });
        response.addListener("end", function () {
            //res.send(postData);
            cb(response,postData);
        });
    });

    request.write(data);
    request.end();
}
function _getSubId(id) {
    var _ret = id;
    var _idx = id.indexOf(_splitflag);
    if (_idx !== -1)
        _ret = id.substr(_idx + 1);
    return _ret;
}

function _getRealId(user, id) {
    return user + _splitflag + id;
}

function _getHttpsGitPathWithUsr(gitInfo){
    var _idx = gitInfo.gitPath.indexOf("https://");
    if( _idx !== -1){
        return "https://"+gitInfo.username+":"+gitInfo.password+"@"+gitInfo.gitPath.substr(_idx+8);
    }else
        return gitInfo.gitPath;
}
function _getHttpsBitPathWithUsr(gitInfo){
    var url = gitInfo.gitPath.split("@")[1];
    if(url){
        return "https://"+gitInfo.username+":"+gitInfo.password+"@"+url;
    }else
        return gitInfo.gitPath;
}

function isContains(str,substr) {
    return str.indexOf(substr) >= 0;
}

function _checkBuildJob(username,job) {
    var query = {user:job.user, id:job.id};
    return new Promise(function (_resolve, _reject) {
       _jobBuild.getWithParam(null,query,function (err,res) {
           if (err){
               logger.error(username + "creat build Job" + job.id + err.message);
               _reject(err);
           }else{
               if (res.length === 0){
                   _resolve(true);
               }else{
                   _resolve(false);
               }
           }
       })
    });
}

function _insertToDB(username,job) {

    return new Promise(function (_resolve, _reject) {
       _jobBuild.insert(null, job, function (err,res) {
          if(err){
              logger.error(username + "build job save mongoDB error" +  job.id + ':'+err.message);
              _reject(err);
          } else{
              _resolve(true);
          }
       })
    });
}

function _creatBuildJob(username,jobinfo) {

    return new Promise(function (_resolve, _reject) {
        _request('/view/' + username + '/createItem?name=' + _getRealId(username,jobinfo.id), 'POST', create_tpl.xml(), function (response, data) {
            var _ret = false;
            var _err = "";
            if(response.statusCode === 200){
                _resolve(true);
            }
            else{
                _err = "create build task error:"+response.body;
                _reject(_err);
                // res.send(myRet(_ret,_err,jobinfo));
            }

        });
    });
}

function _deleteBuildJob(_username,data) {

    console.log(data);
    var url = "/job/" +_getRealId(_username,data.id) + "/doDelete";
    return new Promise(function(_resolve, _reject){
        _request(url,'POST','',function (res, data) {
           if(res.statusCode === 302) {
               _resolve(true);
           }else{
               _reject(data);
           }
        });
    });
}

function rollback(ctx,stack){
    stack.forEach(function(exec){
        var fn = exec.fn;
        fn.apply(ctx,exec.args);
    });
}

/**
 *  svn and git use the same object
 */
router.post('/createJob',function(req, res, next){
    var _username = req.username;
    var data =  req.body;

    //for add project by manual include svn , use the same prop name
    if(data.git_url === undefined || data.clone_url === undefined){
        data.git_url = data.gitPath;
        data.clone_url = data.gitPath;
    }

    //for bitbucket private project
    var _gitpath = data.gitPath;
    if (data.private)
        _gitpath = _gitpath.replace(/:\/\/.*\@/, "://x-token-auth:${access_token}@");
    //build task add by manual , and git protocol is https,and fetch it with username and password
    else if(data.type === 'git' && data.username !== undefined && data.password !== undefined){
        var pathType = isContains(_gitpath,"bitbucket.org");
        if(pathType){
            _gitpath = _getHttpsBitPathWithUsr(data);
        }else{
            _gitpath = _getHttpsGitPathWithUsr(data);
        }
    }

    //set dockerfile path
    var _dockerfile_path = "Dockerfile";
    data.buildContext = data.buildContext || "";
    if(data.buildContext !== "")
        _dockerfile_path = data.buildContext+ '/Dockerfile';

    var _shell = "";
    var _build_context = "";
    if(data.type === 'svn' ){
        //set shell
        _shell = _exec_svn_jenkins_shell;
        _shell = _shell.replace(/#\[username\]/g, (data.username || ""));
        _shell = _shell.replace(/#\[password\]/g, (data.password || ""));
        _shell = _shell.replace(/#\[svn_path\]/g, _gitpath);

        /**
         *  set context
         *  use root path as default build context
         */
        _build_context = '${WORKSPACE}/${TAG_NAME}';

        //set dockerfile path
        _dockerfile_path = '${TAG_NAME}/'+_dockerfile_path;

    }else{
        //set shell
        _shell = _exec_jenkins_shell;
        _shell = _shell.replace(/#\[git_path\]/g, _gitpath);

        /**
         *  set context
         *  use root path as default build context
         */
        _build_context = '${WORKSPACE}';

    }
    var updateUrl='http://'+config.updateAuto.host+":"+config.updateAuto.port;
    _autoupdate_shell =_autoupdate_shell.replace(/#\[updateUrl]/g,updateUrl);
    _autoupdate_shell =_autoupdate_shell.replace(/#\[repoName]/g,_username+'/'+data.id);
    create_tpl('dockerfilePath').text(_dockerfile_path);
    create_tpl('buildContext').text(_build_context);
    create_tpl('repoName').text(_username+'/'+data.id);
    create_tpl('properties isCI').text(data.isCI);
    create_tpl('properties git_name').text(data.name);
    create_tpl('properties git_fullname').text(data.full_name);
    create_tpl('properties git_desc').text(data.description);
    create_tpl('properties git_url').text(data.git_url);
    create_tpl('properties git_ssh_url').text(data.ssh_url);
    create_tpl('properties git_clone_url').text(data.clone_url);
    create_tpl('properties git_isprivate').text(data.private?'true':'false');
    create_tpl('properties git_type').text(data.type);
    create_tpl('builders command').text(_shell);
    create_tpl('publishers tasks script').text(_autoupdate_shell);

    var _jobInfo = data;

    return new Promise(function (resolve, reject) {
        var _rollback_stack = [];

        _creatBuildJob(_username,_jobInfo)
        //insert db
            .then(function () {
                return _checkBuildJob(_username,_jobInfo);
            }).then(function(){

                _rollback_stack.push({
                    fn:_deleteBuildJob,
                    args:[_username,_jobInfo]
                });
                return _insertToDB(_username,_jobInfo);
            }).then(function(){
            //finish
            res.send(myRet(true,'',_jobInfo));
        }).catch(function(err){
            //rollback
            logger.error("creat job error:"+ err.message) ;
            rollback(this,_rollback_stack);
            reject(myRet(false,'',err.message));
        })
    });


    //this is set default docker view


});

router.post('/deleteJob',function(req, res, next) {

    var data = req.body;
    var _username = req.username;
    var url = "http://" + config.jenkins.host + ":" + config.jenkins.port +"/job/" +_getRealId(_username,data.id) + "/doDelete";

    _rep._request(url, 'POST', {"Content-Type": "application/json"},'', function (data,request,response) {
        if(response.statusCode === 302)
            res.send(myRet(true));
        else
            res.send(myRet(false));
    });

    var query = {user:req.username,id:data.id};
    var _ret = false;

    _jobBuild.getWithParam(null,query,function (err,result) {

        if (err) {
            res.send(myRet(_ret,err,''));
        }
        else{
            if (result.length > 0){
                _jobBuild.delWithParam(null,query,function (err,doc) {
                    if (err) {
                        res.send(myRet(_ret,err,''));
                    } else{
                        var resf = doc.result;
                        _ret = true;
                        res.send(myRet(_ret,'',resf));
                    }
                });
            }
        }
    });
});

router.post('/testDocker', function (req,res,next) {
    var param=req.body;
    req.query = req.body;
    callBuild();
    function callBuild(){
        _submitJson = {};
        _submitJson['parameter'] = [];
        var _tagname_p = {};
        _tagname_p.name = 'TAG_NAME';
        _tagname_p.value = param.tag;
        _submitJson['parameter'].push(_tagname_p);
        //old build task not to set  branch type,default is  tag
        if(param.type === 'git' || param.type === 'svn') {
            var _branch_type = {};
            _branch_type.name = 'BRANCH_TYPE';
            if(param.branchtype==undefined){
                _branch_type.value='branch';
            }else {
                _branch_type.value = param.branchtype;
            }
            _submitJson['parameter'].push(_branch_type);
        }else if(param.tag === 'master'){
            var _branch_type = {};
            _branch_type.name = 'BRANCH_TYPE';
            _branch_type.value = 'branch';
            _submitJson['parameter'].push(_branch_type);
        }

        var _auto_manual_p = {};
        _auto_manual_p.name = 'AUTO_MANUAL';
        _auto_manual_p.value = 'test';
        _submitJson['parameter'].push(_auto_manual_p);

        var _status={};
        _status.name='status';
        _status.value=false;
        _submitJson['parameter'].push(_status);

        var _type={};
        _type.name='type';
        _type.value=true;
        _submitJson['parameter'].push(_type);

        _submitJson.statusCode = '303';
        _submitJson.redirectTo = '.';
        var formData = {
            json: JSON.stringify(_submitJson)
        };

        var url = "http://" + config.jenkins.host + ":" + config.jenkins.port + "/job/" + _getRealId(req.username, param.id) + "/build?delay=0sec";
        var _req = require('request').post({url: url,formData: formData}, function (err, httpResponse, body) {
            if (err) {
                //return console.error(err);
                res.send(myRet(false,err.error));
            } else {
                if (httpResponse.statusCode === 303) {
                    //if(dockerfile){
                    //    fs.unlinkSync(dockerfile);
                    //}
                    res.send(myRet(true));
                }
                else
                    res.send(myRet(false));
            }
        });
        /*var form = _req.form();
         form.append('file',fs.createReadStream(dockerfile),{
         contentType:'application/octet-stream',
         knowLength:fs.statSync(dockerfile).size
         })*/
    }
});

router.get('/showDocker', function (req,res,next) {
    var param = req.query;
    var _username = req.username;
    var url = "/view/"+_username+"/job/" + _getRealId(param.user, param.id)+"/ws/"+param.dockeradd+"/Dockerfile/*view*";
    _request(url, 'GET', '', function (response, data) {
        if (response.statusCode === 200) {
            //cheerio.load(data);
            res.send(data);
        }  else{
            res.send(myRet(false));
        }
    });
});

router.get('/getJob',function(req, res, next) {

    var param = req.query;
    var promises = [];
    //get meta info
    promises.push(new Promise(function (resolve, reject){
        var url = "http://" + config.jenkins.host + ":" + config.jenkins.port +"/job/" + _getRealId(req.username, param.id) + "/config.xml";
        _rep._request(url, 'GET',{}, '', function (data,result,response) {
            var ret = {};
            if(response.statusCode === 200){
                var job_conf = cheerio.load(result,{
                    ignoreWhitespace: true,
                    xmlMode: true,
                    lowerCaseTags: false
                });

                ret.id = param.id;
                ret.buildContext = job_conf('buildContext').text().substr(13);
                ret.repoName = job_conf('repoName').text();
                ret.gitPath = job_conf('properties git_clone_url').text();
                ret.name = job_conf('properties git_name').text();
                ret.full_name = job_conf('properties git_fullname').text();
                ret.description = job_conf('properties git_desc').text();
                ret.git_url = job_conf('properties git_url').text();
                ret.ssh_url = job_conf('properties git_ssh_url').text();
                ret.clone_url = job_conf('properties git_clone_url').text();
                ret.private = job_conf('properties git_isprivate').text() == 'true' ? true : false;
                ret.type = job_conf('properties git_type').text();
            }
            resolve(ret);
        });
    }));

    //get builds info
    promises.push(new Promise(function (resolve, reject){
        var url = "http://" + config.jenkins.host + ":" + config.jenkins.port +"/job/" + _getRealId(req.username, param.id) + "/api/json";
        _rep._request(url, 'GET',{}, '', function ( data,result,response) {
            if(response.statusCode === 200){
                var jsonObj = JSON.parse(result);
                var promises = [];
                jsonObj.builds.forEach(function (item) {
                    promises.push(_req(item));
                });

                Promise.all(promises).then(function (retlst) {
                    resolve(retlst);
                });
            }else{
                resolve([]);
            }
        });
        function _req(item) {
            return new Promise(function (resolve, reject) {
                var _st_idx =  item.url.indexOf('/job/');
                var url = item.url + "api/json";
               _rep._request(url, 'GET',{}, '', function (data,result,response) {
                    var ret = {};
                    if (response.statusCode === 200) {
                        var jsonObj = JSON.parse(result);
                        var action = jsonObj.actions[0];
                        var parameters = action.parameters;
                        var len = parameters.length;

                        var num = 0;
                        for (var i =0; i < len; i++){
                            if(parameters[i].name === 'BRANCH_TYPE'){
                                num ++;
                            }
                        }
                        if(num === 1){
                            for (var i = 0; i < len; i++){
                                if(parameters[i].name === 'TAG_NAME'){
                                    ret.tag_name = parameters[i].value;
                                }else if(parameters[i].name === 'BRANCH_TYPE'){
                                    ret.branch_type = parameters[i].value;
                                }else if(parameters[i].name === 'AUTO_MANUAL'){
                                    ret.auto_manual = parameters[i].value;
                                }
                            }
                        }else {
                            var isDocker = 0;
                            for (var i = 0; i < len; i++){
                                if(parameters[i].name === 'TAG_NAME'){
                                    ret.tag_name = parameters[i].value;
                                }else if(parameters[i].name === 'AUTO_MANUAL'){
                                    ret.auto_manual = parameters[i].value;
                                }else if(parameters[i].name === 'Dockerfile'){
                                    isDocker ++;
                                }
                            }
                            if(isDocker === 0){
                                ret.branch_type = 'tag';
                            }else{
                                ret.auto_manual = 'update';
                                ret.branch_type = 'update';
                                ret.tag_name = 'test';
                            }
                        }

                        ret.id = jsonObj.id;
                        ret.result = jsonObj.result;
                        ret.timestamp = jsonObj.timestamp;
                        ret.duration = jsonObj.duration;
                    }
                    resolve(ret);
                });
            });
        }
    }));

    Promise.all(promises).then(function (retlst) {
        res.send(myRet(true,undefined,{
            "meta": retlst[0],
            "builds": retlst[1]
        }));
    });

});

router.get('/getLastBuild',function(req, res, next){
        var param = req.query;
        var url = "/job/" + _getRealId(req.username, param.id) + "/lastBuild/api/json";
        _request(url, 'GET', '', function (response, data) {
            if (response.statusCode === 200) {
                res.send(data);
            } else {
            }
        })
});

router.get('/getBuildConOut',function(req, res, next) {

    var _username = req.username;
    var param = req.query;
    var jobName = param.jobname;
    var buildSeq = param.buildseq;
    var start = param.start;
    var url = "/job/" + _username + "-" + jobName + "/" + buildSeq + "/logText/progressiveHtml?start=" + start;

    _request(url, 'GET', '', function (response, data) {
        if (response.statusCode === 200) {
            var resData = JSON.stringify(data);

            var str = resData.replace(/\\r\\n/g,'\\n');
            var dataArr = str.substring(1,(str.length-1)).split("\\n");
            res.send(dataArr);
        }
    });
});

router.get('/getBuildConOutRunning',function(req, res, next) {

    var _username = req.username;
    var param = req.query;
    var jobName = param.jobname;
    var buildSeq = param.buildseq;
    var start = param.start;
    var url = "/job/" + _username + "-" + jobName + "/" + buildSeq + "/logText/progressiveHtml?start=" + start;

    _request(url, 'GET', '', function (response, data) {
        if (response.statusCode === 200) {
            res.send({data:data,size:response.headers['x-text-size']});
        }
    });
});

router.post('/updateJob',function(req, res, next) {

    var data = req.body;

    if(data.git_url === undefined || data.git_clone_url === undefined){
        data.git_url = data.gitPath;
        data.clone_url = data.gitPath;
    }

    var _gitpath = data.gitPath;
    if (data.private)
        _gitpath = _gitpath.replace(/:\/\/.*\@/, "://x-token-auth:${access_token}@");

    else if(data.type === 'git' && data.username !== undefined && data.password !== undefined){
        var pathType = isContains(_gitpath,"bitbucket.org");
        if(pathType){
            _gitpath = _getHttpsBitPathWithUsr(data);
        }else{
            _gitpath = _getHttpsGitPathWithUsr(data);
        }
    }

    //set dockerfile path
    var _dockerfile_path = "Dockerfile";
    data.buildContext = data.buildContext || "";
    if(data.buildContext !== "")
        _dockerfile_path = data.buildContext+ '/Dockerfile';

    var _shell = "";
    var _build_context = "";
    if(data.type === 'svn' ){
        //set shell
        _shell = _exec_svn_jenkins_shell;
        _shell = _shell.replace(/#\[username\]/g, (data.username || ""));
        _shell = _shell.replace(/#\[password\]/g, (data.password || ""));
        _shell = _shell.replace(/#\[svn_path\]/g, _gitpath);

        _build_context = '${WORKSPACE}/${TAG_NAME}';

        //set dockerfile path
        _dockerfile_path = '${TAG_NAME}/'+_dockerfile_path;

    }else{
        //set shell
        _shell = _exec_jenkins_shell;
        _shell = _shell.replace(/#\[git_path\]/g, _gitpath);

        _build_context = '${WORKSPACE}';

    }

    var url = "/job/" + _getRealId(req.username, data.id) + "/config.xml";


    create_tpl('dockerfilePath').text(_dockerfile_path);
    create_tpl('buildContext').text(_build_context);
    create_tpl('repoName').text(req.username+'/'+data.repoName);
    create_tpl('buildContext').text(_build_context);
    create_tpl('properties git_clone_url').text(data.gitPath);
    create_tpl('properties git_name').text(data.name);
    create_tpl('properties git_fullname').text(data.full_name);
    create_tpl('properties git_desc').text(data.description);
    create_tpl('properties git_url').text(data.git_url);
    create_tpl('properties git_ssh_url').text(data.ssh_url);
    create_tpl('properties git_clone_url').text(data.clone_url);
    create_tpl('properties git_isprivate').text(data.private?'true':'false');
    create_tpl('properties git_type').text(data.type);
    create_tpl('builders command').text(_shell);

    var _jobInfo = {};
    _jobInfo.id = data.id;
    _jobInfo.gitPath = data.gitPath;
    _jobInfo.user = data.user;
    _jobInfo.buildContext = data.buildContext;
    _jobInfo.repoName = data.repoName;
    _jobInfo.isCI = data.isCI;
    _jobInfo.name = data.name;
    _jobInfo.full_name = data.full_name;
    _jobInfo.description = data.description;
    _jobInfo.git_url = data.git_url;
    _jobInfo.ssh_url = data.ssh_url;
    _jobInfo.clone_url = data.clone_url;
    _jobInfo.private = data.private?'true':'false';
    _jobInfo.type = data.type;
    _jobInfo.username = data.username;
    _jobInfo.password = data.password;
    var query = {
        user:req.username,
        id:data.id
    };

    var _ret = false;
    _request(url,'POST',create_tpl.xml(),function(response,data){
        if(response.statusCode === 200){
            _jobBuild.updateField(null,query,_jobInfo,function (err,docs) {
                if (err) {
                    res.send(myRet(_ret,err,''));
                }else{
                    _ret = true;
                    docs.jobInfo = _jobInfo;
                    res.send(myRet(_ret,'',docs));
                }
            });
        }else{
            _ret = false;
            var error = response.statusCode;
            res.send(myRet(_ret,error,''));
        }

    });
});

router.post('/buildJob', function (req, res, next) {

    req.query = req.body;
    var param = req.body;
    var isOld = param.isOld;

    if (isOld === false){
        if(param.type === 'git' || param.type === 'svn'){
            callBuildNew("");
        }else{
            _getTokenAndUser(req,res,callBuildNew,true);
        }

        function callBuildNew(token){
            var status=true;
            var type=true;
            var dockerfile = undefined;
            var _submitJson = {};
            _submitJson['parameter'] = [];
            var _tagname_p = {};
            _tagname_p.name = 'TAG_NAME';
            _tagname_p.value = param.tag;
            _submitJson['parameter'].push(_tagname_p);
            var _token_p = {};
            _token_p.name = 'access_token';
            _token_p.value = token;
            _submitJson['parameter'].push(_token_p);
            //old build task not to set  branch type,default is  tag
            if(param.type === 'git' || param.type === 'svn') {
                var _branch_type = {};
                _branch_type.name = 'BRANCH_TYPE';
                _branch_type.value = param.branchtype;
                _submitJson['parameter'].push(_branch_type);
            }else if(param.tag === 'master'){
                var _branch_type = {};
                _branch_type.name = 'BRANCH_TYPE';
                _branch_type.value = 'branch';
                _submitJson['parameter'].push(_branch_type);
            }

            if(param._dockerfile!==""){
                fs.mkdirSync('./upload');
                fs.writeFileSync('./upload/Dockerfile',param._dockerfile);
                // dockerfile=path.join(__dirname,'../upload/Dockerfile');
                dockerfile=path.join(path.dirname(process.argv[1]),'upload','Dockerfile');

            }

            var _auto_manual_p = {};
            _auto_manual_p.name = 'AUTO_MANUAL';
            _auto_manual_p.value = 'manual';
            _submitJson['parameter'].push(_auto_manual_p);
            var _status={};
            _status.name='status';
            _status.value=status;
            _submitJson['parameter'].push(_status);
            var _type={};
            _type.name='type';
            _type.value=type;
            _submitJson['parameter'].push(_type);


            if(dockerfile !== undefined){
                status =false;
                type=false;
                _submitJson = {};
                _submitJson['parameter'] = [];
                var _status={};
                _status.name='status';
                _status.value=status;
                _submitJson['parameter'].push(_status);
                var _type={};
                _type.name='type';
                _type.value=type;
                _submitJson['parameter'].push(_type);
                var _dockerfile={};
                _dockerfile.name='Dockerfile';
                _dockerfile.file='file0';
                _submitJson['parameter'].push(_dockerfile);
                _submitJson.statusCode = '303';
                _submitJson.redirectTo = '.';
            }

            _submitJson.statusCode = '303';
            _submitJson.redirectTo = '.';


            var formData = {
                json: JSON.stringify(_submitJson)
            };

            if(dockerfile !== undefined){
                formData.file0 = fs.createReadStream(dockerfile);
            }

            var url = "http://" + config.jenkins.host + ":" + config.jenkins.port + "/job/" + _getRealId(req.username, param.id) + "/build?delay=0sec";

            var _ret = false;
            require('request').post({url: url, formData: formData}, function (err, httpResponse, body) {
                if (err) {
                    res.send(myRet(_ret,err,''));
                } else {
                    if (httpResponse.statusCode === 303) {

                        //res.send(myRet(true));
                       _ret = true;
                        res.send(myRet(_ret,'',''));
                    }
                    else
                    {
                        var _ret = false;
                        var _err = httpResponse.statusCode;
                        res.send(myRet(_ret,_err,''));
                    }
                }
                if(dockerfile !== undefined){
                    fs.unlinkSync(dockerfile);
                    fs.rmdirSync('./upload');
                }
            });
        }

    }else{
        if(param.type === 'git' || param.type === 'svn'){
            callBuildOld("");
        }else{
            _getTokenAndUser(req,res,callBuildOld,true);
        }

        function callBuildOld(token){

            var _submitJson = {};
            _submitJson['parameter'] = [];
            var _tagname_p = {};
            _tagname_p.name = 'TAG_NAME';
            _tagname_p.value = param.tag;
            _submitJson['parameter'].push(_tagname_p);
            var _token_p = {};
            _token_p.name = 'access_token';
            _token_p.value = token;
            _submitJson['parameter'].push(_token_p);
            //old build task not to set  branch type,default is  tag
            if(param.type === 'git' || param.type === 'svn') {
                var _branch_type = {};
                _branch_type.name = 'BRANCH_TYPE';
                _branch_type.value = param.branchtype;
                _submitJson['parameter'].push(_branch_type);
            }
            _submitJson.statusCode = '303';
            _submitJson.redirectTo = '.';



            var formData = {
                json: JSON.stringify(_submitJson)
            };

            var url = "http://" + config.jenkins.host + ":" + config.jenkins.port + "/job/" + _getRealId(req.username, param.id) + "/build?delay=0sec";

            require('request').post({url: url, formData: formData}, function (err, httpResponse, body) {
                if (err) {
                    return console.error(err);
                } else {
                    if (httpResponse.statusCode === 303) {
                        res.send(myRet(true));
                    }
                    else
                        res.send(myRet(false));
                }
            });
        }
    }



    /**
     *   if git or svn , no need to request token or get token from db
     */

});

router.get('/stopJob',function(req, res, next){

    var _u_name = req.username;
    var param = req.query;

    var url = "/job/" + _getRealId(_u_name, param.id) + "/" + param.number + "/stop";
    var turl = "/job/" + _getRealId(_u_name, param.id) + "/" + param.number + "/api/json";
    _request(url, 'POST', '', function (response, data) {
        if(response.statusCode === 302){
            _request(turl,'GET','',function (respon,doc) {
                if (respon.statusCode === 200){
                    res.send(myRet(true,'',JSON.parse(doc)));
                }else{
                    res.send(myRet(false,JSON.parse(doc)),'');
                }
            } );
        }
        else {
            res.send(myRet(false, response.statusCode, ''));
        }
    });

});

router.get('/listJobs',function(req, res, next) {

    var _username = req.username;
    var param = req.query;

    var url = "/view/" + _username + "/api/json";
    _request(url, 'GET', '', function (response, data) {
        if (response.statusCode === 200) {
            var jsonObj = JSON.parse(data);
            var promises = [];
            jsonObj.jobs.forEach(function (item) {
                promises.push(_req(item));
            });

            Promise.all(promises).then(function (retlst) {
                res.send(myRet(true,undefined,{
                    "retCode": response.statusCode,
                    "retlst": retlst
                }));
            });
        }
        else {
            res.send(myRet(true,undefined,{
                "retCode": response.statusCode
            }));
        }
        function _req(item) {
            return new Promise(function (resolve, reject) {
                var _st_idx =  item.url.indexOf('/job/') ;
                var url = item.url.substr(_st_idx) + "config.xml";
                _request(url, 'GET', '', function (response, data) {
                    var ret = {};
                    if (response.statusCode === 200) {
                        var job_conf = cheerio.load(data, {
                            ignoreWhitespace: true,
                            xmlMode: true,
                            lowerCaseTags: false
                        });
                        ret.id = _getSubId(item.name);
                        ret.type = job_conf('properties git_type').text();
                        if(ret.type === 'svn'){
                            var dArr = job_conf('dockerfilePath').text().split('/');
                            var dFile = [];
                            for (var i = 1; i < dArr.length - 1; i++){
                                dFile[i - 1] = dArr[i];
                            }
                            ret.buildContext = dFile.join("/");
                        }else{
                            var dArr = job_conf('dockerfilePath').text().split('/');
                            var dFile = [];
                            for(var i = 0; i < dArr.length - 1; i++){
                                dFile[i] = dArr[i];
                            }
                            ret.buildContext = dFile.join("/");
                        }
                        ret.repoName = job_conf('repoName').text().replace(_username+'/','');
                        ret.gitPath = job_conf('properties git_clone_url').text();
                        ret.name = job_conf('properties git_name').text();
                        ret.full_name = job_conf('properties git_fullname').text();
                        ret.description = job_conf('properties git_desc').text();
                        ret.git_url = job_conf('properties git_url').text();
                        ret.ssh_url = job_conf('properties git_ssh_url').text();
                        ret.clone_url = job_conf('properties git_clone_url').text();
                        ret.private = job_conf('properties git_isprivate').text() == 'true' ? true : false;
                        var params = job_conf('properties').text().split(' ');

                        for(var i = 0; i < params.length; i++){
                            if(params[i] === "" || params[i] === " "){
                                params.splice(i,1);
                            }
                        }
                        for(var i = 0; i < params.length; i++){
                            if(params[i] === "" || params[i] === " "){
                                params.splice(i,1);
                            }
                        }
                        ret.params = params;
                    }
                    resolve(ret);
                });
            });
        }
    });
});

router.post('/createUsrView',function(req, res, next){
    var param = req.body;
    //this is also default account "docker"
    var url = "/createView";
    var json = {
        "name":param.id,
        "mode":"hudson.model.ListView"
    };
    var _data = {
        "name":param.id,
        "mode":"hudson.model.ListView",
        "json":JSON.stringify(json),
        "Submit":"OK"
    };

    _request(url, 'POST', qs.stringify(_data), function (response, data) {
        if(response.statusCode === 302){
            res.send(true);
        }
        else
            res.send(false);
    },'application/x-www-form-urlencoded');
});

router.post('/deleteUsrView',function(req, res, next){
    var param = req.body;
    //this is also default account "docker"
    var url = "/view/"+param.id+"/doDelete";

    var _data = {
        "json":{},
        "Submit":"Yes"
    };

    _request(url, 'POST', qs.stringify(_data), function (response, data) {
        if(response.statusCode === 302){
            res.send(true);
        }
        else
            res.send(false);
    },'application/x-www-form-urlencoded');
});

router.param('postId',function (req, res, next, postId) {

    _jobBuild.getWithParam(null,{_id:postId},function (err,result) {
        if (err) return next(err);
        if(!result) return next(new Error('Noting to found'));
        req.query = result[0];
        next();
    });
});

router.post('/webhook/:postId',function (req, res, next) {
    var query = req.query;
    var param = req.body;
    var header = req.headers;
    var content_type = header['content-type'];

    // if(param.zen || (param.payload !== undefined && JSON.parse(param.payload).zen )){
    //     res.send(myRet(true));
    // }else{
        var isCI = (query.isCI === undefined) ? false : query.isCI;
        if (isCI === true){
            var path = query.gitPath;
            var pathType = pathTypeFn(path);
            var branchtype;
            var tag;
            if (content_type === 'application/json'){
                if(param.zen){
                    res.send(myRet(true));
                }else{
                    if(pathType === "github"){
                        var branch = param.ref;
                        var branchInfo = cutString(branch);
                        branchtype = branchTypeFn(branchInfo);
                        tag = branchInfo[1];
                        if(query.type === 'git' || query.type === 'svn'){
                            callBuild("");
                        }else{
                            _getTokenAndUser(req,res,callBuild,true);
                        }
                    }else if(pathType === "bitbucket"){
                        var push = param.push;
                        var changes = push.changes;
                        var newData = changes[0].new;
                        branchtype = newData.type;
                        tag = newData.name;
                        if(query.type === 'git' || query.type === 'svn'){
                            callBuild("");
                        }else{
                            _getTokenAndUser(req,res,callBuild,true);
                        }
                    }
                }

            }else{
                if(JSON.parse(param.payload).zen){
                    res.send(myRet(true));
                }else{
                    if(pathType === "github"){
                        var bodyInfo = JSON.parse(param.payload);
                        var branch = bodyInfo.ref;
                        var branchInfo = cutString(branch);
                        branchtype = branchTypeFn(branchInfo);
                        tag = branchInfo[1];
                        if(query.type === 'git' || query.type === 'svn'){
                            callBuild("");
                        }else{
                            _getTokenAndUser(req,res,callBuild,true);
                        }
                    }
                }
            }

            function callBuild(token){

                var status=true;
                var type=true;
                var _submitJson = {};
                _submitJson['parameter'] = [];
                var _tagname_p = {};
                _tagname_p.name = 'TAG_NAME';
                _tagname_p.value = tag;
                _submitJson['parameter'].push(_tagname_p);
                var _token_p = {};
                _token_p.name = 'access_token';
                _token_p.value = token;
                _submitJson['parameter'].push(_token_p);
                //old build task not to set  branch type,default is  tag
                if(query.type === 'git' || query.type === 'svn' || branchtype === 'branch') {
                    var _branch_type = {};
                    _branch_type.name = 'BRANCH_TYPE';
                    _branch_type.value = branchtype;
                    _submitJson['parameter'].push(_branch_type);
                }
                var _auto_manual_p = {};
                _auto_manual_p.name = 'AUTO_MANUAL';
                _auto_manual_p.value = 'auto';
                _submitJson['parameter'].push(_auto_manual_p);
                _submitJson.statusCode = '303';
                _submitJson.redirectTo = '.';

                var _status={};
                _status.name='status';
                _status.value=status;
                _submitJson['parameter'].push(_status);
                var _type={};
                _type.name='type';
                _type.value=type;
                _submitJson['parameter'].push(_type);

                var formData = {
                    json: JSON.stringify(_submitJson)
                }

                var url = "http://" + config.jenkins.host + ":" + config.jenkins.port + "/job/" + _getRealId(query.user, query.id) + "/build?delay=0sec";

                var _ret = false;
                require('request').post({url: url, formData: formData}, function (err, httpResponse, body) {
                    if (err) {
                        res.send(myRet(_ret,err,''));
                    } else {
                        if (httpResponse.statusCode === 303) {
                            res.send(myRet(true));
                        }
                        else
                            res.send(myRet(_ret,httpResponse.statusCode,''));
                    }
                });
            }

        }else {
            var _mes = "Continuous integration not enabled";
            var _ret = false;
            var _error = "";
            if (res.statusCode === 200){
                res.send(myRet(_ret,_error,_mes));
            }else{
                _ret = false;
                _error = "" + res.body;
                res.send(myRet(_ret,_error,''));
            }
        }

    // }

    function branchTypeFn(branch) {
        var branchs = branch[0];
        if(branchs === 'heads'){
            branchs = 'branch';
        }else if(branchs === 'tags'){
            branchs = 'tag';
        }else{
            branchs = branchs;
        }
        return branchs;
    }

    function cutString (string) {
        var str1 = string.split('refs/');
        var str2 = str1[1];
        var str3 = str2.split('/');
        return str3;
    }
    function isContains(str,substr) {
        return str.indexOf(substr) >= 0;
    }
    function pathTypeFn(path) {
        var pathtype = '';
        if (isContains(path,"github.com") === true){
            pathtype = "github";
        }else if(isContains(path,"bitbucket.org") === true){
            pathtype = "bitbucket"
        }
        return pathtype;
    }

});
router.post('/isOld',function (req,res,next) {
    var param=req.body;
    var query = {user:req.username,id:param.id};
    var _ret=false;
    _jobBuild.getWithParam(null,query,function (err,docs) {
        if(err){
            res.send(myRet(_ret,err));
        }else{
            if(docs&&docs.length>0){
                _ret=true;
                res.send(myRet(_ret));
            }else{
                res.send(myRet(_ret,err));
            }
        }
    })
});

router.post('/getWebhook',function (req,res,next) {
    var param = req.body;

    var _result = "";
    var _ret = false;
    var _error = "";
    _jobBuild.getWithParam(null,param,function (err,docs) {
        if (err){
            res.send(myRet(_ret,err,_result));
        }else{
            if (docs && docs.length > 0){
                _result = docs[0];
                _ret = true;
                res.send(myRet(_ret,_error,_result));
            }else{
                _ret = false;
                // var query = {user:_jobInfo.user, id:_jobInfo.id};
                // _jobBuild.getWithParam(null,query,function (err,result) {
                //     if (err) {
                //         console.error(err.message);
                //     }else{
                //         if (result.length === 0){
                //             _jobBuild.insert(null,_jobInfo,function (err, result) {
                //                 if (err) {
                //                     _ret = false;
                //                     res.send(myRet(_ret,err,''));
                //                 }else{
                //                     res.send(myRet(_ret,_err,_jobInfo));
                //                 }
                //             });
                //         }
                //     }
                //
                // });
                res.send(myRet(_ret,_error,_result));
            }
        }

    });

});

router.post('/updateWebhook',function (req,res,next) {
    var param = req.body;
    _jobBuild.getWithParam(null,param,function (err,docs) {
        if (err){
            logger.error('updatewebhook ' + req.username + '  ' + param.id + 'error: ' + err.message);
            var info = {
                infos:'update webhook error'
            };
            res.send(myRet(false, err.message, info));
        }else{
            if(docs && docs.length > 0){
                var result = docs[0];
                var change = {
                    isCI:!(result.isCI)
                };

                var _ret = false;
                _jobBuild.updateField(null,param,change,function (err,docs) {
                    if (err){
                        res.send(myRet(_ret,err,''));
                    }else{
                        docs.isCI = change.isCI;
                        _ret = true;
                        res.send(myRet(_ret,'',docs));
                    }

                });
            }
        }

    });
});

router.post('/getBuildHistoryCount',function (req, res, next) {

    var param = req.body;
    var quary = {
      user:req.username,
        id:param.id
    };
    var buildHistory = {
        buildHistory:param.buildHistory
    };
    _jobBuild.getWithParam(null,quary,function (err, docs) {
        if(err){
            logger.error('database query error:' + err.message);
            var info = {
              infos:'getException'
            };
            res.send(myRet(false,err.message,info));
        }else{
            //首先判断buildHistory字段是否存在，存在则不作操作，不存在就进行下一步
            //存在则插入字段
            if (docs.length > 0){
                var buildInfo = docs[0];
                if(buildInfo.buildHistory){
                    var count = {
                      buildHistoryCount:buildInfo.buildHistory
                    };
                    res.send(myRet(true,'',count));
                    console.log(buildInfo.buildHistory);
                }else{
                    _jobBuild.update(null,quary,{$inc:buildHistory},function (err, result) {
                       if(err){
                           logger.error(req.username + 'update database build' + param.id + 'error: ' + err.message);
                           var info = {
                             infos:'updateException'
                           };
                           res.send(myRet(false,err.message,info));
                       }else{
                           console.log(result);
                           res.send(myRet(true));
                           //或许判断下result
                       }

                    });
                }
            }else{

                //不存在则保存整个构建的信息进去。包括新加的字段信息
                _jobBuild.insert(null, param, function (err,docs) {
                    if(err){
                        logger.error(req.username + 'insert database build ' + param.id + 'error: ' + err.message);
                        var info = {
                            infos:'insertException'
                        };
                        res.send(myRet(false,err.message,info));
                    }else{
                        console.log(docs);
                        res.send(myRet(true,'',docs));
                    }
                });

            }
        }
    })

});

router.post('/updateBuildHistoryCount',function (req,res,next) {
    var param = req.body;

    _jobBuild.getWithParam(null,param,function (err,docs) {
        if (err){
            logger.error('update buildHistory count ' + req.username + '  ' + param.id + 'error: ' + err.message);
            var info = {
                infos:'update build history count error'
            };
            res.send(myRet(false, err.message, info));
        }else{
            if(docs && docs.length > 0){
                var buildInfo = docs[0];
                var history = buildInfo.buildHistory + 1;
                var change = {
                    buildHistory:history
                };

                var _ret = false;
                _jobBuild.updateField(null,param,change,function (err,docs) {
                    if (err){
                        res.send(myRet(_ret,err,''));
                    }else{
                        _ret = true;
                        res.send(myRet(_ret,'',docs));
                    }

                });
            }
        }

    });
});


module.exports = router;